package com.kehutong.wwin.service.util;

import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

import com.kehutong.wwin.service.entity.Suite;
import com.kehutong.wwin.service.service.SuiteService;
import org.coraframework.http.HttpClient;
import org.coraframework.inject.Inject;
import org.coraframework.inject.Singleton;
import org.coraframework.json.JSON;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.connection.ThreadLocalCache;
import org.coraframework.util.CallBack;

import com.kehutong.common.DoveClient;
import com.kehutong.common.urlconfig.UrlConfig;
import com.kehutong.common.util.Token;
import com.kehutong.wwin.service.entity.Corp;
import com.kehutong.wwin.service.service.CorpService;

@Singleton
public class WwInHttpClient extends UrlConfig {
	private static final Logger logger = LoggerFactory.getLogger(WwInHttpClient.class);
	
	private static final Set<Integer> ILL_TOKEN_SET;
	
	static {
		Set<Integer> map = new HashSet<>();
		map.add(40014);
		map.add(42001);
		ILL_TOKEN_SET = Collections.unmodifiableSet(map);
	}
	
	protected WwInHttpClient() {
		super("tencent", "work_url");
	}


	@Inject
	private DoveClient doveClient;
	@Inject
	private CorpService corpService;

	@Inject
	private SuiteService suiteService;
	
	@Override
	public JSONObject get(String page, CallBack<HttpClient> callBack) throws Exception {
		return super.get(page, callBack);
	}
	
	@Override
	public JSONObject post(String page, CallBack<HttpClient> client) throws Exception {
		return super.post(page, client);
	}

	/**
	 * 获取应用AccessToken
	 * @param token 用户信息
	 * @return 应用AccessToken
	 * @throws Exception 异常
	 */
	public String getAppAccessToken(Token token) throws Exception {
		if (logger.isInfoEnabled()) {
			logger.info("getAppAccessToken:begin Processing getAppAccessToken with Token:{}",token.toString());
		}
		Suite suite =suiteService.getSuiteByCorpId(token.getCompanyNo());
		String accessToken=suiteService.getAppAccessToken(suite);
		if (logger.isInfoEnabled()) {
			logger.info("getAppAccessToken:end Processing getAppAccessToken with accessToken:{}",accessToken);
		}
		return accessToken;
	}

	/**
	 * 获取联系人AccessToken
	 * @param token 用户信息
	 * @return 联系人token
	 * @throws Exception 异常
	 */
	public String getContactAccessToken(Token token) throws Exception {
		if (logger.isInfoEnabled()) {
			logger.info("getContactAccessToken:begin Processing getContactAccessToken with Token:{}",token.toString());
		}
		Corp corp =corpService.getCropByKhtId(token.getCompanyNo());
		String accessToken=corpService.getContactAccessToken(corp);
		if (logger.isInfoEnabled()) {
			logger.info("getContactAccessToken:end Processing getContactAccessToken with accessToken:{}",accessToken);
		}
		return accessToken;
	}


	/**
	 * 获取员工AccessToken
	 * @param token 用户信息
	 * @return 员工token
	 * @throws Exception 异常
	 */
	public String getEmployeeAccessToken(Token token) throws Exception {
		if (logger.isInfoEnabled()) {
			logger.info("getEmployeeAccessToken:begin Processing getEmployeeAccessToken with Token:{}",token.toString());
		}
		Corp corp =corpService.getCropByKhtId(token.getCompanyNo());
		String accessToken=corpService.getEmployeeAccessToken(corp);
		if (logger.isInfoEnabled()) {
			logger.info("getEmployeeAccessToken:end Processing getEmployeeAccessToken with accessToken:{}",accessToken);
		}
		return accessToken;
	}

	public JSONObject getWWin(String page, Token token, boolean isEmployee, CallBack<HttpClient> callBack) throws Exception {
		final HttpClient httpClient = HttpClient.create(getUrl() + page);
		callBack.call(httpClient);
		
		Corp corp = corpService.getCropByKhtId(token.getCompanyNo());
		if (isEmployee) {
			httpClient.addParam("access_token", corpService.getEmployeeAccessToken(corp));
		} else {
			httpClient.addParam("access_token", corpService.getContactAccessToken(corp));
		}

		String text = httpClient.get();
		if (httpClient.getResponseCode() != 200) {
			return httpError(httpClient.getResponseCode(), "http状态错误");
		}
		
		JSONObject rs = JSON.parseObject(text);
		checkIllnessAccessToken(corp, isEmployee, rs.getIntValue("errcode"));
		return rs;
	}
	
	public JSONObject postWWin(String page, Token token, boolean isEmployee, CallBack<HttpClient> callBack) throws Exception {
		final HttpClient httpClient = HttpClient.create(getUrl() + page);
		callBack.call(httpClient);
		
		Corp corp = corpService.getCropByKhtId(token.getCompanyNo());
		if (isEmployee) {
			httpClient.addParam("access_token", corpService.getEmployeeAccessToken(corp));
		} else {
			httpClient.addParam("access_token", corpService.getContactAccessToken(corp));
		}

		String text = httpClient.post();
		if (httpClient.getResponseCode() != 200) {
			return httpError(httpClient.getResponseCode(), "http状态错误");
		}
		
		JSONObject rs = JSON.parseObject(text);
		checkIllnessAccessToken(corp, isEmployee, rs.getIntValue("errcode"));
		
		return rs;
	}
	
	public JSONObject postKht(String page, Token token, CallBack<HttpClient> call) throws Exception {
		return doveClient.post(page, http-> {
			http.addHeader("companyNo", token.getCompanyNo());
			call.call(http);
		});
	}

	public JSONObject postKht(String page, String cropId, CallBack<HttpClient> call) throws Exception {
		return doveClient.post(page, http-> {
			Corp crop = Pool.get(Corp.class, cropId);
			if (Objects.nonNull(crop)) {
				ThreadLocalCache.current().setCorpId(crop.getKhtid());
				http.addHeader("companyNo",crop.getKhtid());
			}
			call.call(http);
		});
	}
	
	private void checkIllnessAccessToken(Corp corp, boolean isEmployee, int errcode) throws Exception {
		if (!ILL_TOKEN_SET.contains(errcode)) {
			return;
		}
		
		if (isEmployee) {
			corp.setEmployeeAccessToken(null);
			corp.setEmployeeAccessTokenExpiredTime(null);
			corpService.getEmployeeAccessToken(corp);
		} else {
			corp.setContactAccessToken(null);
			corp.setContactAccessTokenExpiredTime(null);
			corpService.getContactAccessToken(corp);
		}
	}
	public JSONObject httpError(int code, String message) {
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("code", code);
		jsonObject.put("message", message);

		return jsonObject;
	}
}
